#include "bsp_port.h"
#include "User_App.h"
#include "Modbus_Master.h"

void bsp_uart_SendData(Bsp_Uart_t Uart, uint8_t *data, uint16_t datalen)
{
    USART_TypeDef *UART;
    uint32_t Channel;

    switch (Uart)
    {
    case BSP_UART1:
        UART = USART1;
        Channel = LL_DMA_CHANNEL_1;
        break;

    case BSP_UART2:
        UART = USART2;
        Channel = LL_DMA_CHANNEL_2;
        break;

        //    case BSP_UART3:
        //        UART = USART3;
        //        Channel = LL_DMA_CHANNEL_3;
        //        break;

        //    case BSP_UART4:
        //        UART = USART4;
        //        Channel = LL_DMA_CHANNEL_4;
        //        break;

    default:
        break;
    }

    LL_DMA_SetMemoryAddress(DMA1, Channel, (uint32_t)data);
    LL_DMA_SetDataLength(DMA1, Channel, datalen);
    LL_USART_EnableDMAReq_TX(UART);
    /* Enable DMA Channel Tx */
    LL_DMA_EnableChannel(DMA1, Channel);
}

// 重定向 printf();
int fputc(int ch, FILE *stream)
{
    while (!LL_USART_IsActiveFlag_TXE(USART1))
    {
        ;
    }
    LL_USART_TransmitData8(USART1, (uint8_t)ch);
    return ch;
}
/*  @brief  串口发送函数
    @param  Buf
            要发送的数组
    @param  length
            数据组的长度
    @return 无
    @property 非DMA方式
*/
void bsp_USART_SendBytes(uint8_t *Buf, uint8_t length)
{
#if EnReDe485Pin
    MX_485_TX_MODEL;
#endif
    for (uint8_t i = 0; i < length; i++)
    {
        while (LL_USART_IsActiveFlag_TC(USART1) != 1)
            ;
        LL_USART_TransmitData8(USART1, Buf[i]); // 发送数据
    }
#if EnReDe485Pin
    MX_485_RX_MODEL;
#endif
}
/*  @brief  串口以DMA方式发送数据
    @param  *databuf
            要发送的数据
    @param  datalen
            数据长度
    @return 无
    @property 无
*/
void bsp_USART_DMA_SendBytes(uint8_t *Buf, uint16_t Len)
{
#if 1

#if EnReDe485Pin
    MX_485_TX_MODEL;
#endif
    while (LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) // 检查DMA通道是否启用或禁用
        ;
    LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)Buf); // 告诉DMA它要发送数据的地址
    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, Len);              // 告诉DMA它要发送的数据长度
    LL_USART_EnableDMAReq_TX(USART1);                               // 让USART开启DMA模式传输模式
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);                   // 启用DMA通道
#endif
}

// 定义延时函数
void bsp_Delay_us(uint32_t us)
{
    uint32_t ticks = us * (SystemCoreClock / 10000000); // 计算需要的SysTick时钟周期数
    SysTick->LOAD = ticks - 1;                          // 设置重载值
    SysTick->VAL = 0;                                   // 清空当前值
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;            // 开启SysTick计数器
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0)
        ;              // 等待计数完成
    SysTick->CTRL = 0; // 关闭SysTick计数器
}

/** @brief  水阀控制
 *  @param  state (状态)->
 *          @arg @ref s_CLOSE 关闭
 *          @arg @ref s_OPEN  打开
 *  @return 无
 *  @property 无
 */
void bsp_Ctrl_Water_Valve(Switch_t state)
{
    if (state == s_OPEN)
    {
        mb_write_single_reg(0x01, MB_RW_WATER_VALVE, 1);
    }
    else if (state == s_CLOSE)
    {
        mb_write_single_reg(0x01, MB_RW_WATER_VALVE, 0);
    }
}
/** @brief  加热控制
 *  @param  state (状态)->
 *          @arg @ref s_CLOSE 关闭
 *          @arg @ref s_OPEN  打开
 *  @return 无
 *  @property 无
 */
void bsp_Ctrl_Heat_Switch(Switch_t state)
{
    if (state == s_OPEN)
    {
        mb_write_single_reg(0x01, MB_RW_HEAT_SWITCH, 1);
    }
    else if (state == s_CLOSE)
    {
        mb_write_single_reg(0x01, MB_RW_HEAT_SWITCH, 0);
    }
}
/** @brief  获取 水阀控制 状态
 *  @return s_CLOSE 关闭、s_OPEN  打开
 *  @property 无
 */
Switch_t bsp_Get_Water_Valve(void)
{
    Switch_t KaiGuan = s_ERR;
    uint16_t data_tt = 0;

    mb_read_reg(0x01, MB_RW_WATER_VALVE, 1, &data_tt);

    if (data_tt == s_OPEN)
    {
        KaiGuan = s_OPEN;
    }
    else
    {
        KaiGuan = s_CLOSE;
    }

    return KaiGuan;
}
/** @brief  获取 加热开关 状态
 *  @return s_CLOSE 关闭、s_OPEN  打开
 *  @property 无
 */
Switch_t bsp_Get_Heat_Switch(void)
{
    Switch_t KaiGuan = s_ERR;
    uint16_t data_tt = 0;

    mb_read_reg(0x01, MB_RW_HEAT_SWITCH, 1, &data_tt);

    if (data_tt == s_OPEN)
    {
        KaiGuan = s_OPEN;
    }
    else
    {
        KaiGuan = s_CLOSE;
    }
    return KaiGuan;
}
/** @brief  获取 水壶 状态
 *  @return s_CLOSE 关闭、s_OPEN  打开
 *  @property 无
 */
uint8_t bsp_Get_Kettle_State(void)
{
    Switch_t KaiGuan = s_ERR;
    uint16_t data_tt = 0;

    mb_read_reg(0x01, MB_R_KETTLE_STATE, 1, &data_tt);

    if (data_tt == s_OPEN)
    {
        KaiGuan = s_OPEN;
    }
    else
    {
        KaiGuan = s_CLOSE;
    }
    return KaiGuan;
}
/** @brief  获取 水溢 状态
 *  @return s_CLOSE 关闭、s_OPEN  打开
 *  @property 无
 */
uint8_t bsp_Get_Spill_State(void)
{
    Switch_t KaiGuan = s_ERR;
    uint16_t data_tt = 0;

    mb_read_reg(0x01, MB_R_SPILL_STATE, 1, &data_tt);

    if (data_tt == s_OPEN)
    {
        KaiGuan = s_OPEN;
    }
    else
    {
        KaiGuan = s_CLOSE;
    }
    return KaiGuan;
}

// 看门狗喂狗
void bsp_IWDG_ReloadCounter(void)
{
    // LL_IWDG_ReloadCounter(IWDG); // 喂狗
}
